package com.shell.customer.base.service.impl;

import com.shell.bee.base.exception.UnCheckMsgException;
import com.shell.bee.base.utils.DateUtil;
import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.entity.mvc.RetMsg;
import com.shell.bee.persistence.annotation.Pagination;
import com.shell.bee.persistence.model.PageLimit;
import com.shell.customer.accreditation.AccreditEvent;
import com.shell.customer.accreditation.rx.SetFilesSubscriber;
import com.shell.customer.accreditation.vo.AccreditationVo;
import com.shell.customer.base.dao.CusInfoModifyDao;
import com.shell.customer.base.service.CusInfoAprvService;
import com.shell.customer.base.service.CusModifyService;
import com.shell.customer.base.service.CusRecModService;
import com.shell.customer.base.service.CusTagService;
import com.shell.customer.base.service.CustomerService;
import com.shell.customer.base.vo.CusRecModVo;
import com.shell.customer.group.service.CusGrpService;
import com.shell.customer.invitation.service.InvtCusService;
import com.shell.customer.po.CusInfoAprv;
import com.shell.customer.po.CusRec;
import com.shell.customer.po.CusRecMod;
import com.shell.feign.PubDictionaryFeign;
import com.shell.feign.PubOrganFeign;
import com.shell.feign.PubUserFeign;
import com.shell.feign.UserOrganFeign;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.framework.utils.MessageSender;
import com.shell.governor.modules.message.keyword.CusModifyKeyword;
import com.shell.governor.modules.po.PubDictionary;
import com.shell.governor.organization.po.PubOrgan;
import com.shell.governor.user.vo.PubUserVo;
import com.winchain.feign.TrdAcctFeign;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import rx.Observable;

@Service("cusModifyService")
public class CusModifyServiceImpl implements CusModifyService {
	@Autowired
	private CusInfoModifyDao cusInfoModifyDao;
	@Autowired
	private CustomerService customerService;
	@Autowired
	private SetFilesSubscriber setFilesSubscriber;
	@Autowired
	private CusRecModService cusRecModService;
	@Autowired
	private CusInfoAprvService cusInfoAprvService;
	@Autowired
	private PubDictionaryFeign pubDictionaryFeign;
	@Autowired
	private InvtCusService invtCusService;
	@Autowired
	PubUserFeign PubUserFeign;
	@Autowired
	TrdAcctFeign trdAcctFeign;
	@Autowired
	private CusGrpService cusGrpService;
	@Autowired
	private CusTagService cusTagService;
	@Autowired
	private UserOrganFeign userOrganFeign;
	@Autowired
	private PubOrganFeign pubOrganFeign;

	@Pagination
	public List<CusRecModVo> getAprvCus(PageLimit limit, CusRecModVo recBakVo) {
		if (StringUtil.notEmpty(recBakVo.getCusName())) {
			recBakVo.setCusName(StringUtil.getParameterLike(recBakVo.getCusName()));
		}
		return this.cusInfoModifyDao.getAprvCus(recBakVo);
	}

	public void saveEntInfo(AccreditationVo accreditationVo) {
		CusRec rec = accreditationVo.getCustomerC();

		AccreditEvent accreditEvent = new AccreditEvent();
		accreditEvent.setAccreditationVo(accreditationVo);
		Observable<AccreditEvent> observers = Observable.just(accreditEvent);
		observers.subscribe(this.setFilesSubscriber);

		Map<String, String[]> modItems = getModItems(rec);
		Set<String> modProps = null;
		if (null == modItems) {
			return;
		}
		modProps = modItems.keySet();
		boolean flag = true;
		for (String key : modProps) {
			if ((!key.equals("province")) && (!key.equals("address")) && (!key.equals("city"))) {
				flag = false;
				break;
			}
		}
		if (flag) {
			this.customerService.saveOrUpdate(rec);
			return;
		}
		CusRecMod recBak = new CusRecMod();
		BeanUtils.copyProperties(rec, recBak);

		CusInfoAprv cusInfoAprv = new CusInfoAprv();
		if ((!"FINNER".equals(rec.getCusType())) && (!this.cusTagService.hasTag(rec.getCusId(), null, "OPERATOR"))
				&& (!this.cusTagService.hasTag(rec.getCusId(), null, "FOCAL_CO"))) {
			cusInfoAprv.setAprvId(SystemUtil.getUUID());
			cusInfoAprv.setBusinessId(recBak.getCusId());

			cusInfoAprv.setApprover(rec.getGrpId());
			cusInfoAprv.setModNum(Integer.valueOf(modItems.keySet().size()));
			cusInfoAprv.setApplyer(CommonDataUtil.getUserName());
			cusInfoAprv.setCreateTime(DateUtil.getSystemDateTime());
			cusInfoAprv.setOperator(CommonDataUtil.getUserId());
			recBak.setCusState("2");
			this.cusInfoAprvService.saveOrUpdate(cusInfoAprv);

			this.cusRecModService.delete(recBak.getCusId());
			this.cusRecModService.saveOrUpdate(recBak);

			String template = "MT06005";
			CusModifyKeyword keyWord = new CusModifyKeyword();
			keyWord.setApplyDate(DateUtil.parseDate(cusInfoAprv.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"));
			keyWord.setCusName(CommonDataUtil.getCurEntName());
			String senderId = CommonDataUtil.getUserId();

			String aprvCusId = this.cusGrpService.findGroupEnt(cusInfoAprv.getApprover(), "GROUP_FIRST_TRIAL");

			MessageSender.sendMessageByTmpl(senderId, template, keyWord, aprvCusId);
		} else {
			rec.setCusState("E");
			this.customerService.saveOrUpdate(rec);
		}
	}

	public CusRecModVo selectCusRecModVo(String cusId) {
		CusRecModVo cusRecModVo = this.cusInfoModifyDao.selectCusRecModVo(cusId);
		CusRec customer = null;
		if ((cusRecModVo == null) || ("E".equals(cusRecModVo.getCusState()))) {
			cusRecModVo = new CusRecModVo();
			customer = (CusRec) this.customerService.selectByKey(cusId);
			if (customer == null) {
				return null;
			}
			BeanUtils.copyProperties(customer, cusRecModVo);
		}
		PubDictionary dict = this.pubDictionaryFeign.getDictionaryByCode(cusRecModVo.getCusType());
		String roleStr = dict.getExtension2();
		if (StringUtil.notEmpty(roleStr)) {
			String[] roles = roleStr.split(",");
			List<PubUserVo> admins = this.PubUserFeign.selectUserByRoleCodeAndEntId(cusId, roles[0]);
			String authFileRlatIds = "";
			for (PubUserVo admin : admins) {
				if (StringUtil.notEmpty(admin.getAuthFileRlatId())) {
					if (authFileRlatIds.equals("")) {
						authFileRlatIds = admin.getAuthFileRlatId();
					} else {
						authFileRlatIds = authFileRlatIds + "," + admin.getAuthFileRlatId();
					}
				}
			}
			cusRecModVo.setAuthFileRlatIds(authFileRlatIds);
		}
		return cusRecModVo;
	}

	public Map<String, String[]> getModItems(CusRec newObj) {
		CusRec oldObj = (CusRec) this.customerService.selectByKey(newObj.getCusId());
		Map<String, String[]> modItems = null;
		try {
			for (Field field : CusRec.class.getDeclaredFields()) {
				StringBuffer sb = new StringBuffer();
				sb.append("get");
				String fieldName = field.getName();
				sb.append(fieldName.substring(0, 1).toUpperCase());
				sb.append(fieldName.substring(1));
				Method method = CusRec.class.getMethod(sb.toString(), new Class[0]);

				Object oldVal = method.invoke(oldObj, new Object[0]);
				Object newVal = method.invoke(newObj, new Object[0]);
				String oldStr = oldVal == null ? "" : oldVal.toString();
				String newStr = newVal == null ? "" : newVal.toString();
				if ((!newStr.equals(oldStr)) && (!"cusState".equals(fieldName))) {
					if (null == modItems) {
						modItems = new HashMap();
					}
					modItems.put(fieldName, new String[] { oldStr, newStr });
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new UnCheckMsgException("����������������");
		}
		return modItems;
	}

	public RetMsg trialPass(CusInfoAprv aprv, String curState) {
		CusRecMod bak = (CusRecMod) this.cusRecModService.selectByKey(aprv.getBusinessId());
		bak.setCusState("3");
		int rs = this.cusInfoModifyDao.updateCusRecModOptimistically(bak, curState);
		if (rs != 1) {
			return new RetMsg("error", false, "������������������������");
		}
		aprv.setAprvId(SystemUtil.getUUID());
		aprv.setCreateTime(DateUtil.getSystemDateTime());
		aprv.setOperator(CommonDataUtil.getUserId());
		this.cusInfoAprvService.saveOrUpdate(aprv);

		String template = "MT06006";
		CusModifyKeyword keyWord = new CusModifyKeyword();
		keyWord.setApplyDate(DateUtil.parseDate(aprv.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"));
		keyWord.setCusName(bak.getCusName());
		keyWord.setOperator(CommonDataUtil.getUserName());
		String senderId = CommonDataUtil.getUserId();

		String lastTrialCusId = this.cusGrpService.findGroupEnt(aprv.getApprover(), "GROUP_LAST_TRIAL");
		MessageSender.sendMessageByTmpl(senderId, template, keyWord, lastTrialCusId);
		return new RetMsg("success", true, "����������������������");
	}

	public RetMsg finalPass(CusInfoAprv aprv, String curState) {
		CusRecMod bak = (CusRecMod) this.cusRecModService.selectByKey(aprv.getBusinessId());
		String bakCusName = bak.getCusName();
		bak.setCusState("E");
		int rs = this.cusInfoModifyDao.updateCusRecModOptimistically(bak, curState);
		if (rs != 1) {
			return new RetMsg("error", false, "������������������������");
		}
		aprv.setAprvId(SystemUtil.getUUID());
		aprv.setCreateTime(DateUtil.getSystemDateTime());
		aprv.setOperator(CommonDataUtil.getUserId());
		this.cusInfoAprvService.saveOrUpdate(aprv);

		CusRec cusRec = (CusRec) this.customerService.selectByKey(aprv.getBusinessId());
		String currCusName = cusRec.getCusName();
		BeanUtils.copyProperties(bak, cusRec);
		this.customerService.saveOrUpdate(cusRec);
		if (!bakCusName.equals(currCusName)) {
			this.invtCusService.updateIvtCusNameByinviteeId(bakCusName, cusRec.getCusId());
			pushToPubOrgan(cusRec.getCusId(), bakCusName);
		}
		String template = "MT06008";
		CusModifyKeyword keyWord = new CusModifyKeyword();
		keyWord.setApplyDate(DateUtil.parseDate(aprv.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"));
		String senderId = CommonDataUtil.getUserId();
		MessageSender.sendMessageByTmpl(senderId, template, keyWord, bak.getCusId());

		return new RetMsg("success", true, "������������");
	}

	private void pushToPubOrgan(String cusId, String cusName) {
		PubOrgan organ = new PubOrgan();
		organ.setOrganId(cusId);
		organ.setOrganName(cusName);
		this.pubOrganFeign.updateNotNull(organ);
	}

	public void trialReject(CusInfoAprv aprv) {
		CusRecMod bak = (CusRecMod) this.cusRecModService.selectByKey(aprv.getBusinessId());
		bak.setCusState("5");
		this.cusRecModService.saveOrUpdate(bak);
		aprv.setAprvId(SystemUtil.getUUID());
		aprv.setCreateTime(DateUtil.getSystemDateTime());
		aprv.setOperator(CommonDataUtil.getUserId());
		this.cusInfoAprvService.saveOrUpdate(aprv);

		String template = "MT06007";
		CusModifyKeyword keyWord = new CusModifyKeyword();
		keyWord.setApplyDate(DateUtil.parseDate(aprv.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"));
		keyWord.setOperator(CommonDataUtil.getUserName());
		keyWord.setRemark(aprv.getAprvRemark());
		String senderId = CommonDataUtil.getUserId();

		MessageSender.sendMessageByTmpl(senderId, template, keyWord, bak.getCusId());
	}

	public void finalReject(CusInfoAprv aprv) {
		CusRecMod bak = (CusRecMod) this.cusRecModService.selectByKey(aprv.getBusinessId());
		bak.setCusState("2");
		this.cusRecModService.saveOrUpdate(bak);
		aprv.setAprvId(SystemUtil.getUUID());
		aprv.setCreateTime(DateUtil.getSystemDateTime());
		aprv.setOperator(CommonDataUtil.getUserId());
		this.cusInfoAprvService.saveOrUpdate(aprv);

		String template = "MT06009";
		CusModifyKeyword keyWord = new CusModifyKeyword();
		keyWord.setApplyDate(DateUtil.parseDate(aprv.getCreateTime(), "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd"));
		keyWord.setCusName(bak.getCusName());
		keyWord.setOperator(CommonDataUtil.getUserName());
		keyWord.setRemark(aprv.getAprvRemark());
		String senderId = CommonDataUtil.getUserId();

		String firstTrialCusId = this.cusGrpService.findGroupEnt(aprv.getApprover(), "GROUP_FIRST_TRIAL");
		MessageSender.sendMessageByTmpl(senderId, template, keyWord, firstTrialCusId);
	}
}
